package conlon.utils;

import conlon.constant.Constant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

@Component
public class ServiceThreadLocal {

    /**
     * 线程内容
     */
    private static final ThreadLocal<Map<String, Object>> VALUE = ThreadLocal.withInitial(HashMap::new);

    public static final String CUSTOM_DADA_KEY = "_custom_data_key_";

    /**
     * 是否开启mycat切库
     * @return
     */
    public static Boolean getMycatEnable() {
        return (Boolean) VALUE.get().get(Constant.MYCAT_ENABLE_KEY);
    }

    public static void setMycatEnable(boolean enable) {
        VALUE.get().put(Constant.MYCAT_ENABLE_KEY, enable);
    }

    public static Optional<Boolean> getMycatEnableOpt() {
        return Optional.ofNullable(getMycatEnable());
    }

    /**
     * 是否只读Schema
     * @return
     */
    public static boolean getSchemaIsReadonly() {
        return Optional.ofNullable((Boolean) VALUE.get().get(Constant.SCHEMA_IS_READONLY_KEY)).orElse(Boolean.FALSE);
    }

    public static void setSchemaIsReadonly(boolean schemaIsReadonly) {
        VALUE.get().put(Constant.SCHEMA_IS_READONLY_KEY, schemaIsReadonly);
    }

    /**
     * Schema
     * @return
     */
    public static String getSchema() {
        return (String) VALUE.get().get(Constant.SCHEMA_KEY);
    }

    public static void setSchema(String schema) {
        VALUE.get().put(Constant.SCHEMA_KEY, schema);
    }

    public static Optional<String> getSchemaOpt() {
        return Optional.ofNullable(getSchema());
    }

    /**
     * 是否是租户
     * @return
     */
    public static Boolean getTenantEnable() {
        return (Boolean) VALUE.get().get(Constant.TENANT_ENABLE_KEY);
    }

    public static void setTenantEnable(boolean enable) {
        VALUE.get().put(Constant.TENANT_ENABLE_KEY, enable);
    }

    public static Optional<Boolean> getTenantEnableOpt() {
        return Optional.ofNullable(getTenantEnable());
    }

    /**
     * 租户Id
     * @return
     */
    public static Integer getTenantCode() {
        return (Integer) VALUE.get().get(Constant.TENANT_CODE_KEY);
    }

    public static void setTenantCode(int tenantCode) {
        VALUE.get().put(Constant.TENANT_CODE_KEY, tenantCode);
    }

    public static Optional<Integer> getTenantCodeOpt() {
        return Optional.ofNullable(getTenantCode());
    }

    /**
     * 用户Id
     * @return
     */
    public static Long getUserId() {
        return (Long) VALUE.get().get(Constant.USER_ID_KEY);
    }

    public static void setUserId(Long userId) {
        VALUE.get().put(Constant.USER_ID_KEY, userId);
    }

    public static Optional<Long> getUserIdOpt() {
        return Optional.ofNullable(getUserId());
    }

    /**
     * 用户姓名
     * @return
     */
    public static String getUserName() {
        return (String) VALUE.get().get(Constant.USER_NAME_KEY);
    }

    public static void setUserName(String userName) {
        VALUE.get().put(Constant.USER_NAME_KEY, userName);
    }

    public static Optional<String> getUserNameOpt() {
        return Optional.ofNullable(getUserName());
    }

    /**
     * 当前登录用户id
     * @return
     */
    public static Long getCurrentUserId() {
        return (Long) VALUE.get().get(Constant.CURRENT_USER_ID_KEY);
    }

    public static void setCurrentUserId(Long currentUserId) {
        VALUE.get().put(Constant.CURRENT_USER_ID_KEY, currentUserId);
    }

    public static Optional<Long> getCurrentUserIdOpt() {
        return Optional.ofNullable(getCurrentUserId());
    }

    /**
     * 当前登录用户姓名
     * @return
     */
    public static String getCurrentUserName() {
        return (String) VALUE.get().get(Constant.CURRENT_USER_NAME_KEY);
    }

    public static void setCurrentUserName(String currentUserName) {
        VALUE.get().put(Constant.CURRENT_USER_NAME_KEY, currentUserName);
    }

    public static Optional<String> getCurrentUserNameOpt() {
        return Optional.ofNullable(getCurrentUserName());
    }

    /**
     * 数据权限 - 仓库id数组
     * @return
     */
    public static String getWarehouseIdArr() {
        return (String) VALUE.get().get(Constant.WAREHOUSE_ID_ARR_KEY);
    }

    public static void setWarehouseIdArr(String warehouseIdArr) {
        VALUE.get().put(Constant.WAREHOUSE_ID_ARR_KEY, warehouseIdArr);
    }

    public static Optional<String> getWarehouseIdArrOpt() {
        return Optional.ofNullable(getWarehouseIdArr());
    }

    /**
     * 用户鉴权序列
     * @return
     */
    public static String getAuthSeq() {
        return (String) VALUE.get().get(Constant.USER_AUTH_SEQ_ARR);
    }

    public static void setAuthSeq(String userAuthSeq) {
        VALUE.get().put(Constant.USER_AUTH_SEQ_ARR, userAuthSeq);
    }

    public static Optional<String> getAuthSeqOpt() {
        return Optional.ofNullable(getAuthSeq());
    }

    public static Map<String, String> customData() {
        VALUE.get().putIfAbsent(CUSTOM_DADA_KEY, new HashMap<String, String>());
        return (Map<String, String>) VALUE.get().get(CUSTOM_DADA_KEY);
    }

    /**
     * 设置自定义key
     * @param key
     * @param value
     */
    public static void putCustomData(String key, String value) {
        MDC.put(key, value);
        customData().put(key, value);
    }

    /**
     * 获取自定义key
     * @param key
     */
    public static Optional<String> getCustomDataOpt(String key) {
        return Optional.ofNullable(getCustomData(key));
    }

    /**
     * 获取自定义key
     * @param key
     */
    public static String getCustomData(String key) {
        return customData().get(key);
    }

    /**
     * 清除线程中保存的数据
     */
    public static void clear() {
        customData().keySet().forEach(MDC::remove);
        VALUE.remove();
    }

}
